package com.bds.btcdc.web.service;

import com.alibaba.fastjson.JSONObject;
import com.bds.btcdc.web.model.strategy.*;
import com.bds.btcdc.web.utils.Const;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by DongChenchen on 2018/3/13.
 **/
@Service
public class StrategyService {
    /**
     * 涨跌判定测试
     * 需要数据：10分钟前  历史成交数据（使用卖价）
     */
    public void execute(){
        KieContainer kieContainer = KieServices.Factory.get().getKieClasspathContainer();
        long start = System.currentTimeMillis();
        KieSession session =kieContainer.newKieSession("updownKSession");
        UpOrDown ud=new UpOrDown();
        List<BigDecimal> old_buys=new ArrayList<BigDecimal>();
        old_buys.add(BigDecimal.valueOf(2.1));
        old_buys.add(BigDecimal.valueOf(2.4));
        old_buys.add(BigDecimal.valueOf(2.6));
        List<BigDecimal> old_sells=new ArrayList<BigDecimal>();
        old_sells.add(BigDecimal.valueOf(2.2));
        old_sells.add(BigDecimal.valueOf(2.4));
        old_sells.add(BigDecimal.valueOf(2.5));
        List<BigDecimal> now_buys=new ArrayList<BigDecimal>();
        now_buys.add(BigDecimal.valueOf(1.1));
        now_buys.add(BigDecimal.valueOf(1.3));
        now_buys.add(BigDecimal.valueOf(1.5));
        List<BigDecimal> now_sells=new ArrayList<BigDecimal>();
        now_sells.add(BigDecimal.valueOf(3.4));
        now_sells.add(BigDecimal.valueOf(3.5));
        now_sells.add(BigDecimal.valueOf(3.6));
        ud.setNow_buys(now_buys);
        ud.setNow_sells(now_sells);
        ud.setOld_buys(old_buys);
        ud.setOld_sells(old_sells);
        ud.setThld_start(0.2);
        ud.setThld_end(1.8);
        session.insert(ud);
        int rules=session.fireAllRules();
        System.out.println("fire "+rules+" rules");
        session.dispose();
        System.out.println(System.currentTimeMillis() - start + "ms");
        System.out.println(JSONObject.toJSONString(ud));
    }

    /**
     * 执行方向测试
     */
    public void execute2(){
        KieContainer kieContainer = KieServices.Factory.get().getKieClasspathContainer();
        long start = System.currentTimeMillis();
        KieSession session =kieContainer .newKieSession("directionKSession");
        Direction ud=new Direction();
        ud.setUp_or_down_a(0);
        ud.setUp_or_down_b(1);
        session.insert(ud);
        int rules=session.fireAllRules();
        System.out.println("fire "+rules+" rules");
        session.dispose();
        System.out.println(System.currentTimeMillis() - start + "ms");
        System.out.println(JSONObject.toJSONString(ud));

    }
    /**
     * 吃单判定测试
     * 需要数据：
     *      波动率     每分钟 数字货币的价格   1.历史成交数据（使用卖价）
     *      盘口收益率                       2.深度数据
     *
     */
    public void execute3(){
        KieContainer kieContainer = KieServices.Factory.get().getKieClasspathContainer();
        long start = System.currentTimeMillis();
        KieSession session =kieContainer .newKieSession("orderKSession");
        Order order = new Order();
        //1.价格波动率需要的参数
            BigDecimal [] datas=new BigDecimal[]{
                    BigDecimal.valueOf(9001.1),
                    BigDecimal.valueOf(9010.1),
                    BigDecimal.valueOf(9100.1),
                    BigDecimal.valueOf(9000.1),
                    BigDecimal.valueOf(9020.1),
            };
            List<BigDecimal> data=new ArrayList<>();
            data.addAll(Arrays.asList(datas));
        order.setPrice_per_minute(data);
        order.setPrice_change_rate_threshold(BigDecimal.valueOf(0.2));
        //2.盘口收益率需要的参数
        order.setDisk_buy_one(BigDecimal.valueOf(2.1));
        order.setDisk_sell_one(BigDecimal.valueOf(1.1));
        order.setDisk_buy_count(BigDecimal.valueOf(0.1));
        order.setDisk_sell_count(BigDecimal.valueOf(0.1));
        order.setDisk_buy_fee(BigDecimal.valueOf(0.001));
        order.setDisk_sell_fee(BigDecimal.valueOf(0.001));
        order.setDisk_yield_threshold(BigDecimal.valueOf(30.1));
        //3.预期收益率需要的参数
        order.setExpected_buy_one(BigDecimal.valueOf(1.1));
        order.setExpected_sell_one(BigDecimal.valueOf(2.1));
        order.setExpected_buy_count(BigDecimal.valueOf(0.2));
        order.setExpected_sell_count(BigDecimal.valueOf(0.2));
        order.setExpected_buy_poundage(BigDecimal.valueOf(0.001));
        order.setExpected_sell_poundage(BigDecimal.valueOf(0.001));
        order.setExpected_yield_threshold(BigDecimal.valueOf(3.1));
        //4.交易失败风险需要的参数
        order.setTransaction_fail_risk_threshold(BigDecimal.valueOf(0.6));
        session.insert(order);
        int rules=session.fireAllRules();
        System.out.println("fire "+rules+" rules");
        session.dispose();
        System.out.println(System.currentTimeMillis() - start + "ms");
        System.out.println(JSONObject.toJSONString(order));

    }

    /**
     * 回购测试
     *    * 需要数据：
     *       1.历史成交数据
     *       2.历史交易记录（订单）
     */
    public void execute4(){
        KieContainer kieContainer = KieServices.Factory.get().getKieClasspathContainer();
        long start = System.currentTimeMillis();
        KieSession session =kieContainer .newKieSession("buybackKSession");
        BuyBack ud=new BuyBack();
        List<BuyBackOneCoin>bcoins=new ArrayList();
            BuyBackOneCoin bcoin1=new BuyBackOneCoin();
            BuyBackOneCoin bcoin2=new BuyBackOneCoin();
                CoinPrice coin1=new CoinPrice("BTC",BigDecimal.valueOf(9000.0),BigDecimal.valueOf(1.0));
                CoinPrice coin2=new CoinPrice("LTC",BigDecimal.valueOf(2000.0),BigDecimal.valueOf(3.0));
            bcoin1.setCoin(coin1);
            bcoin1.setOrder_avg_price(BigDecimal.valueOf(8000.1));
            bcoin1.setUp_price(BigDecimal.valueOf(291.1));
            bcoin2.setCoin(coin2);
            bcoin2.setOrder_avg_price(BigDecimal.valueOf(8001.1));
            bcoin2.setUp_price(BigDecimal.valueOf(100.1));
            bcoins.add(bcoin1);
            bcoins.add(bcoin2);
        ud.setCoins(bcoins);
        ud.setOrder_avg_price_threshold(BigDecimal.valueOf(0.035));
        ud.setSum_profit(BigDecimal.valueOf(2222.33));
        session.insert(ud);
        int rules=session.fireAllRules();
        System.out.println("fire "+rules+" rules");
        session.dispose();
        System.out.println(System.currentTimeMillis() - start + "ms");
        System.out.println(JSONObject.toJSONString(ud));
    }

    /**
     * 量化回流测试
     * 调用一次，执行一次对冲
     *   需要数据：
     *       1.历史成交数据
     *       2.账户信息
     */
    public void execute5(){
        KieContainer kieContainer = KieServices.Factory.get().getKieClasspathContainer();
        long start = System.currentTimeMillis();
        KieSession session =kieContainer .newKieSession("quanKSession");
        QuantitativeTs quan=new QuantitativeTs();
            List<ExchangeTransaction> exchas=new ArrayList<>();
            //交易所1
            ExchangeTransaction exchange1=new ExchangeTransaction();
                //1.交易记录（同一个币种的交易记录）
                List<Transaction> trans=new ArrayList<>();//exchange1交易所 10小时内交易记录
                    Transaction tran1=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    Transaction tran2=new Transaction("BTC",BigDecimal.valueOf(2.0),new Date());
                    Transaction tran3=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    Transaction tran4=new Transaction("BTC",BigDecimal.valueOf(2.0),new Date());
                trans.add(tran1);
                trans.add(tran2);
                trans.add(tran3);
                trans.add(tran4);
                exchange1.setTransactions(trans);
                //2.用户基准值
                exchange1.setMoney_sum_threshold(BigDecimal.valueOf(10000.0));
                exchange1.setCoin_sum_threshold(BigDecimal.valueOf(10.0));
                //3.用户实际的资金,币的个数
                exchange1.setMoney_sum(BigDecimal.valueOf(60000.0));  //钱多币少
                exchange1.setCoin_sum(BigDecimal.valueOf(0.01));
                //4.吃单判定数据
                exchange1.setOrder(getOrder("",""));
            //交易所2
            ExchangeTransaction exchange2=new ExchangeTransaction();
                //1.交易记录（同一个币种的交易记录）
                List<Transaction> trans2=new ArrayList<>();//exchange1交易所 10小时内交易记录
                    Transaction tran11=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    Transaction tran22=new Transaction("BTC",BigDecimal.valueOf(2.0),new Date());
                    trans2.add(tran11);
                    trans2.add(tran22);
                exchange2.setTransactions(trans2);
                //2.用户基准值
                exchange2.setMoney_sum_threshold(BigDecimal.valueOf(10000.0));
                exchange2.setCoin_sum_threshold(BigDecimal.valueOf(10.0));
                //3.用户实际的资金,币的个数
                exchange2.setMoney_sum(BigDecimal.valueOf(15000.0));  //钱多币少
                exchange2.setCoin_sum(BigDecimal.valueOf(0.02));
                //4.吃单判定数据
                exchange2.setOrder(getOrder("",""));
            //交易所3
            ExchangeTransaction exchange3=new ExchangeTransaction();
                //1.交易记录（同一个币种的交易记录）
                List<Transaction> trans3=new ArrayList<>();//exchange1交易所 10小时内交易记录
                    Transaction tran31=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    Transaction tran32=new Transaction("BTC",BigDecimal.valueOf(2.0),new Date());
                    Transaction tran33=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    trans3.add(tran31);
                    trans3.add(tran32);
                    trans3.add(tran33);
                exchange3.setTransactions(trans3);
                //2.用户基准值
                exchange3.setMoney_sum_threshold(BigDecimal.valueOf(10000.0));
                exchange3.setCoin_sum_threshold(BigDecimal.valueOf(7.0));
                //3.用户实际的资金,币的个数
                exchange3.setMoney_sum(BigDecimal.valueOf(90000.0));  //钱多币少
                exchange3.setCoin_sum(BigDecimal.valueOf(0.01));
                //4.吃单判定数据
                exchange3.setOrder(getOrder("",""));

            //交易所4
            ExchangeTransaction exchange4=new ExchangeTransaction();
                //1.交易记录（同一个币种的交易记录）
                List<Transaction> trans4=new ArrayList<>();//exchange1交易所 10小时内交易记录
                    Transaction tran41=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    trans4.add(tran41);
                exchange4.setTransactions(trans4);
                //2.用户基准值
                exchange4.setMoney_sum_threshold(BigDecimal.valueOf(10000.0));
                exchange4.setCoin_sum_threshold(BigDecimal.valueOf(7.0));
                //3.用户实际的资金,币的个数
                exchange4.setMoney_sum(BigDecimal.valueOf(2000.0));  //钱少币多
                exchange4.setCoin_sum(BigDecimal.valueOf(117.0));
                //4.吃单判定数据
                exchange4.setOrder(getOrder("",""));
            //交易所5
            ExchangeTransaction exchange5=new ExchangeTransaction();
                //1.交易记录（同一个币种的交易记录）
                List<Transaction> trans5=new ArrayList<>();//exchange1交易所 10小时内交易记录
                    Transaction tra51=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    Transaction tra52=new Transaction("BTC",BigDecimal.valueOf(2.0),new Date());
                    Transaction tra53=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    Transaction tra54=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    trans5.add(tra54);
                    trans5.add(tra51);
                    trans5.add(tra52);
                    trans5.add(tra53);
                exchange5.setTransactions(trans5);
                //2.用户基准值
                exchange5.setMoney_sum_threshold(BigDecimal.valueOf(10000.0));
                exchange5.setCoin_sum_threshold(BigDecimal.valueOf(1.0));
                //3.用户实际的资金,币的个数
                exchange5.setMoney_sum(BigDecimal.valueOf(100.0));  //钱少币多
                exchange5.setCoin_sum(BigDecimal.valueOf(39.0));
                //4.吃单判定数据
                exchange5.setOrder(getOrder("",""));
            //交易所6
            ExchangeTransaction exchange6=new ExchangeTransaction();
                //1.交易记录（同一个币种的交易记录）
                List<Transaction> trans6=new ArrayList<>();//exchange1交易所 10小时内交易记录
                    Transaction tra61=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    Transaction tra62=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    Transaction tra63=new Transaction("BTC",BigDecimal.valueOf(1.0),new Date());
                    trans6.add(tra61);
                    trans6.add(tra62);
                    trans6.add(tra63);
                exchange6.setTransactions(trans6);
                //2.用户基准值
                exchange6.setMoney_sum_threshold(BigDecimal.valueOf(10000.0));
                exchange6.setCoin_sum_threshold(BigDecimal.valueOf(7.0));
                //3.用户实际的资金,币的个数
                exchange6.setMoney_sum(BigDecimal.valueOf(500.0));  //钱少币多
                exchange6.setCoin_sum(BigDecimal.valueOf(1333.0));
                //4.吃单判定数据
                exchange6.setOrder(getOrder("",""));
            exchas.add(exchange1);
            exchas.add(exchange2);
            exchas.add(exchange3);
            exchas.add(exchange4);
            exchas.add(exchange5);
            exchas.add(exchange6);
            quan.setTransactionHis(exchas);
        session.insert(quan);
        int rules=session.fireAllRules();
        System.out.println("fire "+rules+" rules");
        session.dispose();

        //吃单判定
        List<ExchangeTransaction> exchanges_low = quan.getExchanges_low();//所有币少的交易所
        //遍历每一个需要回流的交易所,进行吃单判定，直到找到一个可以吃单的。 吃单过后，从头开始量化回测
        for(ExchangeTransaction exchange_a:exchanges_low){
            List<ExchangeTransaction> inverse_exchanges = exchange_a.getInverse_exchanges();
            if(!CollectionUtils.isEmpty(inverse_exchanges)) {
                for (ExchangeTransaction exchange_b : inverse_exchanges) {
                    if (null==exchange_b.getHas_pair()||exchange_b.getHas_pair()) {//没有匹配过
                        Order order = exchange_b.getOrder();
                        //设置 预期收益率
                        order.setExpected_yield_threshold(Const.EXPECT_PROFIT);
                        KieSession order_session =kieContainer .newKieSession("orderKSession");
                        order_session.insert(order);
                        int rules2 = order_session.fireAllRules();
                        System.out.println("fire " + rules2 + " rules");
                        order_session.dispose();
                        if (order.getCanOrder()) {//可以下单
                            exchange_b.setHas_pair(true);
                            Map<ExchangeTransaction, ExchangeTransaction> result = quan.getResult();
                            result.put(exchange_a, exchange_b);
                            quan.setResult(result);
                            break;
                        }
                    }
                }
            }
        }//end for
        System.out.println(System.currentTimeMillis() - start + "ms");
        System.out.println(JSONObject.toJSONString(quan));
    }
    private Order getOrder(String exchange,String coin){
        Order order = new Order();
            //1.价格波动率需要的参数
            BigDecimal [] datas=new BigDecimal[]{
                    BigDecimal.valueOf(9001.1),
                    BigDecimal.valueOf(9010.1),
                    BigDecimal.valueOf(9100.1),
                    BigDecimal.valueOf(9000.1),
                    BigDecimal.valueOf(9020.1),
            };
            List<BigDecimal> data=new ArrayList<>();
            data.addAll(Arrays.asList(datas));
            order.setPrice_per_minute(data);
            order.setPrice_change_rate_threshold(BigDecimal.valueOf(0.2));
            //2.盘口收益率需要的参数
            order.setDisk_buy_one(BigDecimal.valueOf(1.1));
            order.setDisk_sell_one(BigDecimal.valueOf(2.1));
            order.setDisk_buy_count(BigDecimal.valueOf(0.1));
            order.setDisk_sell_count(BigDecimal.valueOf(0.1));
            order.setDisk_buy_fee(BigDecimal.valueOf(0.001));
            order.setDisk_sell_fee(BigDecimal.valueOf(0.001));
            order.setDisk_yield_threshold(BigDecimal.valueOf(30.1));
            //3.预期收益率需要的参数
            order.setExpected_buy_one(BigDecimal.valueOf(1.1));
            order.setExpected_sell_one(BigDecimal.valueOf(2.1));
            order.setExpected_buy_count(BigDecimal.valueOf(0.2));
            order.setExpected_sell_count(BigDecimal.valueOf(0.2));
            order.setExpected_buy_poundage(BigDecimal.valueOf(0.001));
            order.setExpected_sell_poundage(BigDecimal.valueOf(0.001));
            order.setExpected_yield_threshold(BigDecimal.valueOf(3.1));
            //4.交易失败风险需要的参数
            order.setTransaction_fail_risk_threshold(BigDecimal.valueOf(44.6));
        return order;
    }

}
